#include "dpLibrary\dpWindows.h"
#include "dpLibrary\graphics.h"
#include "dpLibrary\audio.h"

#include "winlib.h"
#include <time.h>

#include "AFObjectFactory.h"
#include "AFGraphics.h"
#include "AFBitmapConverter.h"
#include "AFInput.h"
#include "AFDebugging.h"

#ifdef _DEBUG
#pragma comment(lib, "dpLibrary/dpLibraryDebug.lib")
#else
#pragma comment(lib, "dpLibrary/dpLibrary.lib")
#endif

#define ClientWidth 800
#define ClientHeight 600


dpGraphics* graphicsSystem = NULL;
dpAudio* audio = NULL;
dpPixel* screenBuffer = NULL;

/* Audio Setup */
dpSound* music1 = NULL;
dpSound* music2 = NULL;
int playing1 = 0;
int playing2 = 0;

uint GameIsRunning = 1;
int InputReceived = 0;

//The message handling procedure for the game
LRESULT WINAPI MessageHandler(HWND hWnd,   //The window the message is for (ours in this case)
                              UINT msg,   //The message type
                              WPARAM wParam, //The primary data for the message
                              LPARAM lParam) //The secondary data for the message (if any)
{

  DWORD dwAltKeyMask = 0;
  //See what type of message it is
  switch(msg)
  {  
  case WM_CHAR: //A character key was pressed
    {
      break;
    }
  case WM_SIZE:
    {
      int clientWidth  = LOWORD(lParam); 
      int clientHeight = HIWORD(lParam);
      dpResize(graphicsSystem, clientWidth, clientHeight);
      break;
    }
  case WM_KEYDOWN:
    {
      //change key values to true when key is down
      switch(wParam)
      {
      case 'W':
        keyboard.wKey = 1;        
        break;
      case 'A':
        keyboard.aKey = 1;        
        break;
      case 'S':
        keyboard.sKey = 1;        
        break;
      case 'D':
        keyboard.dKey = 1;        
        break;
      case 'R':
        keyboard.rKey = 1;
        break;
      case 'Y':
        keyboard.yKey = 1;
        break;
      case 'T':
        keyboard.tKey = 1;
        break;
	  case 'X':
		  keyboard.xKey = 1;
		  break;
	  case 'Z':
		  keyboard.zKey = 1;
		  break;
	  case 'C':
		  keyboard.cKey = 1;
		  break;
	  case 'V':
		  keyboard.vKey = 1;
		  break;
      case VK_SPACE:
        keyboard.spaceKey = 1;
        break;
      case VK_ESCAPE:
        GameIsRunning = 0;
        break;            
      }
      break; 
    }
  case WM_KEYUP:
    {
      //change key values to false when that key is lifted
      switch(wParam)
      {
      case 'W':
        keyboard.wKey = 0;
        break;
      case 'A':
        keyboard.aKey = 0;
        break;
      case 'S':
        keyboard.sKey = 0;
        break;
      case 'D':
        keyboard.dKey = 0;
        break;
      case 'R':
        keyboard.rKey = 0;
        break;
      case 'Y':
        keyboard.yKey = 0;
        break;
      case 'T':
        keyboard.tKey = 0;
        break;
	  case 'X':
		  keyboard.xKey = 0;
		  break;
	  case 'Z':
		  keyboard.zKey = 0;
		  break;
	  case 'C':
		  keyboard.cKey = 0;
		  break;
	  case 'V':
		  keyboard.vKey = 0;
		  break;
      case VK_SPACE:
        keyboard.spaceKey = 0;
        break;
      }
      break;
    }
  case WM_CLOSE:
    {
      GameIsRunning = 0;
      break;
    }
  case WM_SYSKEYDOWN:
    {
      //Eat the WM_SYSKEYDOWN message to prevent freezing the game when
      //the alt key is pressed
      switch( wParam )
      {
      case VK_LMENU:
      case VK_RMENU:
        return 0;
      case VK_F4:
        //Check for Alt F4
        dwAltKeyMask = ( 1 << 29 );
        if( ( lParam & dwAltKeyMask ) != 0 )
          PostQuitMessage(0);
        return 0;
      }
      return 0;//
    }
  default:
    //We didn't completely handle the message, so pass it on for 
    //Windows to handle.
    return DefWindowProc(hWnd, msg, wParam, lParam);
  }
  return 0;
}

INT WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, 
                   LPSTR commandLine, INT commandShow)
{
  HWND windowHandle = 0;

  /* Bitmap Files  */
  SPRITEIMAGE hud, test, small, enemyImage, playerImage; //map
  //char* filename = "bitmap_files/24bitBitmapTest.bmp";
  char* smallfile = "bitmap_files/sampletext.bmp";
  char* testfile = "bitmap_files/solidgold.bmp";
  //char* filename = "bitmap_files/BitmapTest.bmp";
  //char* hudfile = "bitmap_files/ryu.bmp";
  char* hudfile = "bitmap_files/hud.bmp";
  //char* testfile = "bitmap_files/BitmapTest.bmp";
  //char* mapfile = "bitmap_files/map_1000_1000.bmp";
  char* enemyfile = "bitmap_files/phenemy.bmp";
  char* playerfile = "bitmap_files/phplayer.bmp";

  /* END FILES */

  Sprite* player         = CreateSprite(ORANGE, CENTER_OF_SCREEN_X, 
	  CENTER_OF_SCREEN_Y, 25000, 25000, 20, 20, "player");  //named the player sprite
  Sprite* enemyList      = CreateSprite(BLACK, 0, 0, 25000, 25000, 0, 0, "enemy"); //named the enemy sprite
  /*Sprite* collisionTest  = CreateSprite(GREEN, 160, 120, 10, 10);*/
  Sprite* enemyListHead = enemyList;    

  AFDebugConsole();

  windowHandle = InitializeWindows(instance, MessageHandler, ClientWidth, 
    ClientHeight);

  graphicsSystem = dpInitializeGraphics(windowHandle, ClientWidth, 
    ClientHeight);

  screenBuffer = (dpPixel*)AFInitializeGraphics();

  audio = dpInitializeAudio();

  /* Load in the Bitmaps */
  hud = ReadInBitmap(hudfile);
  test = ReadInBitmap(testfile);
  small = ReadInBitmap(smallfile);
  //map = ReadInBitmap(mapfile);
  enemyImage = ReadInBitmap(enemyfile);
  playerImage = ReadInBitmap(playerfile);

  /* Load in Audio */
  music1 = dpLoadSoundFromFile(audio, "audio_files/01 - Oboe Concerto, Op 9 N2 in D Minor, Adagio.mp3");
  //music2 = dpLoadSoundFromFile(audio, "audio_files/25 - DRUMS SYNCOPATED RHYTHM.mp3");
  music2 = dpLoadSoundFromFile(audio, "audio_files/DrumRhythmLong.wav");

  /* Loading Function Coming Soon */


  /* initialize random seed: */
  srand ((unsigned int)time(NULL));
  //int rNum = (rand() % 310 + 1);  //give me a wierd semi colon related error??

  while(GameIsRunning)
  {
    WindowsSystemUpdate();
    ClearBuffer();

	/* Draw Map */
	//DrawBitmap(screenBuffer, map);

	/* Draw the bitmap below everything else */
	if (keyboard.zKey)
	{
		DrawBitmap(screenBuffer, test);
	}
	if (keyboard.xKey)
	{
		DrawBitmap(screenBuffer, small);
	}
	


    if (keyboard.wKey || keyboard.aKey || keyboard.sKey || keyboard.dKey)
    {
      InputReceived = 1;
    }
    else
    {
      InputReceived = 0;
    }   

    CollisionDetection(player, enemyListHead);
    UpdateGraphics(player, enemyListHead);

    // Prints the player's location in the world in the
    // debug window.
    if(InputReceived)
    {
      printf("Player coordinates:\n");
      printf("screenX: %i ", player->screen.X);
      printf("screenY: %i ", player->screen.Y);
      printf("worldX: %i ",  player->world.X);
      printf("worldY: %i \n", player->world.Y);
    }    

    //input logic
    if(keyboard.wKey)
    {      
      player->world.Y -= 2;
    }
    if(keyboard.aKey)
    {     
      player->world.X -= 2;      
    }
    if(keyboard.sKey)
    {     
      player->world.Y += 2;
    }
    if(keyboard.dKey)
    {     
      player->world.X += 2;
    }
    if(keyboard.rKey)
    {
      /*int sxRandom = rand() % 310 + 1;
      int syRandom = rand() % 310 + 1;    */  
      int wxRandom = (rand() % dpScreenWidth  + 1) + 
        (player->world.X - (dpScreenWidth  / 2) );
      int wyRandom = (rand() % dpScreenHeight + 1) + 
        (player->world.Y - (dpScreenHeight/ 2) );      
      
      enemyList->next = CreateSprite(BLACK, 0, 0, 
        wxRandom, wyRandom, 20, 20, "enemy");
      enemyList = enemyList->next;      
    }
    if(keyboard.yKey)
    {
      PrintRandomSprites();
    }
    if(keyboard.tKey)
    {
      CheckeredPattern();
    }
    if(keyboard.spaceKey)
    { 
      FireUpward(player);
    }

	/* Draw the Temporary HUD */
	DrawBitmap(screenBuffer, hud);

	
	/* Play Music */
	
	if (keyboard.cKey && playing1 == 0)
	{
		dpPlaySound(audio, music1);
		playing1 = 1;
	}
	if (keyboard.vKey && playing2 == 0)
	{
		dpPlaySound(audio, music2);
		playing2 = 1;
	}

    dpUpdateAudio(audio);

    dpUpload(graphicsSystem, screenBuffer);
    dpRender(graphicsSystem);
  }
  dpShutdownAudio(audio);
  dpShutdownGraphics(graphicsSystem);
}

